
/** 手写promise
 * 1.一个类,在执行这个类时，需要传一个执行器，执行器会立即执行
 * 2.promise三种状态及改变 pending -> fullfilled; pending -> rejected
 * 3.resolve和reject是用来更改状态的
 * 4.then内部做的事情就是判断状态, **then方法是被定义在原型对象中的**
 * 5.then记录成功的值和失败的原因
 * 6.链式调用，传值
 * 
 * 简单的promise实现
 * 第三步：then多次调用
 *
 */
const PENDING = 'pending'; // 等待
const FULLFILLED = 'fullfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
    constructor(executor){
        // 执行器立即执行
        executor(this.resolve,this.reject) 
    }
    status = PENDING; // 初始状态 默认pending
    value = undefined;// 成功的值
    reason = undefined; // 失败的原因
    successCallback = [] // 成功回调 2.为异步任务准备 3.变成数组解决多次调用问题
    failCallback = [] // 失败回调 2.为异步任务准备 3.变成数组解决多次调用问题
    resolve= value => { // this指向问题！
        if(this.status !== PENDING) return // 状态pending 才可修改
        this.status = FULLFILLED; // 修改promise状态 成功 一旦确定就不可更改
        this.value = value; // 保存成功之后的值
        // 2.成功回调是否存在
        // this.successCallback && this.successCallback(value)
        // 3.循环数组调用 从前往后执行 获取第一个并在数组中删除
        while (this.successCallback.length){
            this.successCallback.shift()(value)
        }
    }

    reject= reason => {
        if(this.status !== PENDING) return // 状态pending 才可修改
        this.status = REJECTED;// 修改promise状态 成功 一旦确定就不可更改
        this.reason = reason;
        // 2.失败回调是否存在
        // this.failCallback && this.failCallback(reason)
        // 3.循环数组调用 从前往后执行 获取第一个并在数组中删除
        while (this.failCallback.length){
            this.failCallback.shift()(reason)
        }
    }

    then(successCallback,failCallback){// 定义在原型对象之中 ？？？？
        //判断状态
        if(this.status === FULLFILLED){ // 成功
            successCallback(this.value)
        }else if(this.status === REJECTED){ // 失败
            failCallback(this.reason)
        }else { // 2.等待状态 3.push到数组中
            this.successCallback.push(successCallback);
            this.failCallback.push(failCallback);
        }
    }
}

export default MyPromise